package com.kaifamiao.demo.d0825;

public class Demo02 {

    public static void main(String[] args) {
        /*
         单例模式： 在应用中只有一个实例
            1. 构造 私有
            2. 类内部创建对象
            3. 对外提供方法获取对象

          创建的对象的过程
          static 和 non-static 的区别
          构造的作用
         */

//        HungrySingleton instance = HungrySingleton.getInstance();
//        HungrySingleton instance1 = HungrySingleton.getInstance();
//
//        System.out.println(instance == instance1);

        EnumSingleton enumSingleton = EnumSingleton.SINGLETON;
        EnumSingleton enumSingleton1 = EnumSingleton.SINGLETON;
        enumSingleton.method();
    }

}

// 饿汉式（静态常量）
class HungrySingleton {

    // 构造私有
    private HungrySingleton(){}

    // 内部创建一个对象实例
    private static final HungrySingleton INSTANCE = new HungrySingleton();

    // 对外提供一个共有的静态方法，用于获取对象实例
    public static HungrySingleton getInstance(){
        return INSTANCE;
    }

}
// 饿汉式
class HungrySingleton1{
    // 构造私有
    private HungrySingleton1(){}

    // 内部创建一个对象实例
    private static HungrySingleton1 INSTANCE;

    static {
        INSTANCE = new HungrySingleton1();
    }
    // 对外提供一个共有的静态方法，用于获取对象实例
    public static HungrySingleton1 getInstance(){
        return INSTANCE;
    }
}

// 懒汉
class LazySingleton{

    private LazySingleton(){}

    private static LazySingleton instance;

    public static LazySingleton getInstance(){
        if (instance == null){
            instance = new LazySingleton();
        }
        return instance;
    }
}

// 静态内部类
class InnerClassSingleton {

    // 1. 构造器私有
    private InnerClassSingleton(){}

    // 2. 创建静态内部类
    private static class SingletonInstance{
        // 创建实例
        private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
    }

    // 3. 对外提供共有访问方法
    public static InnerClassSingleton getInstance(){
        // 调用静态内部类，第一次调用时会装载 SingletonInstance 这个是线程安全的(由JVM保证),而且只会装载一次
        return SingletonInstance.INSTANCE;
    }
}

// 枚举是天然的单例模式
enum EnumSingleton{
    // 枚举元素，代表了 EnumSingleton 的一个实例
    SINGLETON;

    public void method(){
        // 功能处理
    }
}

